﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mimoza.AgentLayer.Communication;
using Mimoza.Transport;

namespace Mimoza.ServiceLayer
{
    public class ServicePolicyManager : BaseObject
    {
        public ServicePolicyManager(Configuration config)
            : base(config)
        {
            m_policySynchronizer = new ServicePolicySynchronizer(config);
            m_timeSynchronizer = new ServiceTimeSynchronizer(config);
        }

        override public void Init()
        {
            Configuration.ObjectLayer.PolicyRepository.OnObjectChanged += OnPolicyChanged;
        }

        override public void Shutdown()
        {
            Configuration.ObjectLayer.PolicyRepository.OnObjectChanged -= OnPolicyChanged;
        }

        void OnPolicyChanged(object sender, Mimoza.ObjectLayer.ObjectLayer_ObjectChangedEventArgs eventArg)
        {
            if (!(eventArg.Object is Mimoza.ObjectLayer.Policy))
            {
                Common.Logger.Log.Error("ServicePolicyManager.OnPolicyChanged ERROR Object is not policy.");
                return;
            }

            Mimoza.ObjectLayer.Policy modifiedPolicy = eventArg.Object as Mimoza.ObjectLayer.Policy;

            if (modifiedPolicy.Record == null)
            {
                Common.Logger.Log.Error("ServicePolicyManager.OnPolicyChanged ERROR Policy is empty.");
                return;
            }

            Common.Logger.Log.Info("ServicePolicyManager.OnPolicyChanged operation - '" + eventArg.EventType.ToString() +
                "' id - '" + modifiedPolicy.ID.ToString() + "' Name - '" + modifiedPolicy.Name + "'.");

            UpdateEffectivePolicyId(modifiedPolicy.Parent, Guid.NewGuid());
        }

        void UpdateEffectivePolicyId(Mimoza.ObjectLayer.Container container, Guid newEffectivePolicyId)
        {
            container.EffectivePolicyID = newEffectivePolicyId;
            ObjectLayer.ContainerRepository.Update(container);

            InitiateConnectionsToContainerHosts(container);

            IEnumerable<Mimoza.ObjectLayer.Container> childsContainers = container.GetChilds();
            if (childsContainers != null)
            {
                foreach (Mimoza.ObjectLayer.Container childContainer in childsContainers)
                {
                    UpdateEffectivePolicyId(childContainer, newEffectivePolicyId);
                }
            }
        }

        void InitiateConnectionsToContainerHosts(Mimoza.ObjectLayer.Container container)
        {
            Common.Logger.Log.Info("ServicePolicyManager.InitiateConnectionsToContainerHosts container id - '" + 
                container.ID.ToString() + "' container name - '" + container.Name + "'.");

            foreach (ObjectLayer.Host host in container.GetHosts())
            {
                Configuration.HostsConnectionInitiator.AddHost(host);
            }
        }

        ServicePolicySynchronizer m_policySynchronizer;
        ServiceTimeSynchronizer m_timeSynchronizer;
    }
}
